#include "MutationOperators.h"

namespace jcrada {

    //REGULAR MUTATION

    TreeOfNodes* RegularMutation::mutate( const TreeOfNodes& victim, TreeGenerator& mutation_generator ) {
        TreeOfNodes* mutant = victim.clone();

        Node* victim_node = mutant->findNodeUsingBFS(getRandomMutationPoint().nextInt(0, mutant->getSize()));

        Node* parent = victim_node->getParent();

        int parent_arity = parent ? parent->getChildPosition(victim_node) : -1;

        delete victim_node;

        Node* mutation = mutation_generator.createRandomSubtree(getMaxMutationDepth(),
                getRandomMethod().nextBool() ? TreeGenerator::M_FULL : TreeGenerator::M_GROW);

        if (parent) {
            mutation->moveTo(parent, parent_arity);
        } else {
            mutant->setRoot(mutation);
        }

        return mutant;
    }

    //FAIR-SIZE MUTATION

    TreeOfNodes* FairSizeMutation::mutate( const TreeOfNodes& victim, TreeGenerator& mutation_generator ) {
        TreeOfNodes* mutant = victim.clone();
        
        int depth = mutant->getDepth();
        TreeOfNodes* mutation = mutation_generator.createRandomTree(depth, TreeGenerator::M_GROW);
        _fair_size_crossover.crossover(*mutant,*mutation);
        delete mutation;
        return mutant;
    }
}
